package com.code.wordhelper.controller;

import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import com.code.wordhelper.config.Constants;
import com.code.wordhelper.config.LibreOfficeConfig;
import com.code.wordhelper.config.WordConfig;
import com.code.wordhelper.model.ImageByteData;
import com.code.wordhelper.model.Result;
import com.code.wordhelper.model.ResultCode;
import com.code.wordhelper.testbean.Course;
import com.code.wordhelper.testbean.Person;
import com.code.wordhelper.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.jodconverter.core.DocumentConverter;
import org.jodconverter.core.office.OfficeManager;
import org.jodconverter.local.LocalConverter;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

@Slf4j
@RestController
public class WordController {
    @Autowired
    private WordConfig wordConfig;
    @Autowired
    private LibreOfficeConfig libreOfficeConfig;
    @Autowired(required = false)
    private OfficeManager officeManager;

    //根据模板生成数据包括页码和目录)
    @RequestMapping("template")
    public Result template(@RequestParam("file") MultipartFile file, @RequestParam(value = "data", required = false) String data, @RequestParam("example") Boolean example) {
        try {
            String tmpFileName = UUID.randomUUID().toString().replace("-", "");
            Path tempFile = Paths.get(wordConfig.getBaseDir(), tmpFileName + ".docx");
            file.transferTo(tempFile);

            Path target = Paths.get(wordConfig.getBaseDir(), tmpFileName + ".docx");

            Map<String, Object> dataMap = null;
            if (example) {
                dataMap = templateData();
            }else{

            }

            XWPFDocument doc = new XWPFDocument(new FileInputStream(tempFile.toString()));//创建word对象

            ParagraphTemplateUtils.replaceParagraphs(doc, dataMap);
            CirculateTemplateUtils.handleCirculates(doc, dataMap);
            TableTemplateUtils.replaceTables(doc, dataMap);

            FileOutputStream out = new FileOutputStream(target.toString());
            doc.write(out);
            out.close();
            doc.close();

            return Result.ok("http://localhost:8900/" + Constants.FILE_PREFIX + "/" + tmpFileName + ".docx");
        } catch (Exception e) {
            log.error("{}", e);
        }

        return Result.failure(ResultCode.TEMPLATE_ERROR);
    }

    //添加水印
    @RequestMapping("watermark")
    public Result watermark(@RequestParam("file") MultipartFile file, @RequestParam("text") String text, @RequestParam("fontSize") Integer fontSize, @RequestParam(value = "textHeight", required = false) Integer textHeight
            , @RequestParam("textColor") String textColor, @RequestParam(value = "rotation", required = false) String rotation, @RequestParam("num") Integer num) {
        try {
            String tmpFileName = UUID.randomUUID().toString().replace("-", "");
            Path tempFile = Paths.get(wordConfig.getBaseDir(), tmpFileName + ".docx");
            file.transferTo(tempFile);

            Path target = Paths.get(wordConfig.getBaseDir(), tmpFileName + ".docx");

            XWPFDocument doc = new XWPFDocument(new FileInputStream(tempFile.toString()));//创建word对象

            CTSectPr sectPr = doc.getDocument().getBody().getSectPr();
            int h = 0;
            int w = 0;
            num = num - 2;
            if (sectPr != null) {
                CTPageSz pageSize = sectPr.getPgSz();
                h = pageSize.getH().intValue() / 20 / (num);
                w = pageSize.getW().intValue() / 20 / (num);
            } else {
                h = 100;
            }
            text = text + "        ";
            StringBuilder buffer = new StringBuilder(text.length() * w);
            for (int i = 0; i < 10; i++) {
                buffer.append(text);
            }

            if (fontSize < 50) {
                textHeight = fontSize * 2;
            } else {
                textHeight = fontSize;
            }
            System.out.println(h);

            for (int i = -1; i <= num + 1; i++) {
                WaterMarkUtils.waterMark(doc, buffer.toString(), textColor, fontSize, textHeight, i * h, "-30");
            }

            FileOutputStream out = new FileOutputStream(target.toString());
            doc.write(out);
            out.close();
            doc.close();

            return Result.ok("http://localhost:8900/" + Constants.FILE_PREFIX + "/" + tmpFileName + ".docx");
        } catch (Exception e) {
            log.error("{}", e);
        }

        return Result.failure(ResultCode.ADD_WATER_ERROR);
    }

    //转换成pdf
    @RequestMapping("convertToPdf")
    public Result convertToPdf(@RequestParam("file") MultipartFile file, @RequestParam("filename") String filename) {
        try {
            String tmpFileName = UUID.randomUUID().toString().replace("-", "");
            Path tempFile = Paths.get(wordConfig.getBaseDir(), tmpFileName + ".docx");
            file.transferTo(tempFile);

            Path target = Paths.get(wordConfig.getBaseDir(), tmpFileName + ".pdf");

            if (libreOfficeConfig.getEnable() && officeManager.isRunning()) {
                log.info("使用libreOffice转换.....");
                DocumentConverter documentConverter = LocalConverter.make(officeManager);
                documentConverter.convert(tempFile.toFile()).to(target.toFile()).execute();

                return Result.ok("http://localhost:8900/" + Constants.FILE_PREFIX + "/" + tmpFileName + ".pdf");
            } else {
                log.info("使用aspose转换.....");
                FileOutputStream os = new FileOutputStream(target.toString());
                Document doc = new Document(tempFile.toString());
                doc.save(os, SaveFormat.PDF);
                os.close();

                return Result.ok("http://localhost:8900/" + Constants.FILE_PREFIX + "/" + tmpFileName + ".pdf");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return Result.failure(ResultCode.PREVIEW_ERROR);
    }

    //word合并
    @RequestMapping("merge")
    public String merge() {
        return "------";
    }

    //电子签章
    @RequestMapping("signature")
    public String signature() {
        return "------";
    }

    private static Map<String, Object> templateData() {
        Map<String, Object> dataMap = new HashMap<>();

        Course c1 = new Course("一年级", "语文");
        Course c2 = new Course("一年级", "数学");
        Course c3 = new Course("二年级", "英语");
        Course c4 = new Course("二年级", "语文");
        Course c5 = new Course("二年级", "思政");


        List<String> pics = Base64Utils.getPic();
        Base64.Encoder encoder = Base64.getEncoder();
        List<ImageByteData> imageByteDatas = new ArrayList<>(pics.size());
        pics.forEach((pic) -> {
            ImageByteData imageByteData = new ImageByteData();
            imageByteData.setBase64(pic);
            imageByteData.setFilename("aaa");
            imageByteData.setExt("");
            imageByteDatas.add(imageByteData);
        });
        Person p1 = new Person("张三", "男", "教师", "大学", Arrays.asList(c1, c2), imageByteDatas.get(0));
        Person p2 = new Person("李四", "女", "校长", "博士", Arrays.asList(c3, c4, c5), imageByteDatas.get(1));

        List<Object> persons = Arrays.asList(p1, p2);
        dataMap.put("persons", persons);
        dataMap.put("teacherNum", 2);
        dataMap.put("courseNum", 5);

        ImageByteData imageByteData = new ImageByteData();
        imageByteData.setBase64(Base64Utils.getImg());
        imageByteData.setExt("jpg");
        imageByteData.setFilename("aaaa.jpg");

        Map<String, Object> bridge = new HashMap<>();
        bridge.put("name", "南京长江大桥");
        bridge.put("location", "南京");
        bridge.put("buildTime", "2022-10-10");
        bridge.put("length", "1000m");
        bridge.put("desc", "它是长江上第一座由中国自行设计和建造的双层式铁路、公路两用桥梁");
        bridge.put("img", imageByteData);
        bridge.put("city", "南京");

        dataMap.put("bridge", bridge);
        dataMap.put("item", 2);

        return dataMap;
    }
}
